﻿using Crosstales.FB.Util;
using FluentFTP;
using Jinndev;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Threading;
using UnityEngine;

namespace Assets.Scripts.UI.Upload {

    public class FtpUploader : IUploader, IProgress<double> {

        public event Action<object> Log;
        public event Action<int, int, long> Progress;
        public event Action<double> SubProgress;
        public event Action Complete;
        public bool uploading { get; set; }

        private FtpClient client;
        private Thread thread;

        private UploadConfig config;
        private string localPath;

        public FtpUploader(UploadConfig config, string localPath) {
            this.config = config;
            this.localPath = localPath;
        }

        public void Dispose() {
            if (client != null) {
                client.Dispose();
                client = null;
            }
            if (thread != null) {
                thread.Abort();
                thread = null;
            }
        }

        public void StartUpload() {
            thread = new Thread(Upload);
            thread.Start(config);
        }

        private void Upload(object state) {
            client = new FtpClient(config.host, config.port, new NetworkCredential(config.username, config.password));
            client.DataConnectionConnectTimeout = 5000;
            client.ConnectTimeout = 5000;
            client.DataConnectionReadTimeout = 5000;
            client.ReadTimeout = 5000;
            //client.DataConnectionType = FtpDataConnectionType.PASV;

            Log("连接中...");
            try {
                client.Connect();
            }
            catch (System.Exception e) {
                Debug.LogException(e);
                Log(e);
                client.Dispose();
                client = null;
                thread = null;
                return;
            }

            Log("连接成功");

            string[] files = Directory.GetFiles(localPath, "*", SearchOption.AllDirectories);

            Log("上传: " + config.localPath + " 到 " + config.remotePath);

            // 排个序
            List<string> fileList = new List<string>(files.Length);
            for (int i = 0; i < files.Length; i++) {
                string file = files[i];
                if (file.EndsWith(".html"))
                    fileList.Add(file);
                else
                    fileList.Insert(0, file);
            }

            long totalSize = 0;
            for (int i = 0; i < fileList.Count; i++) {
                string file = fileList[i];
                string subPath = file.Substring(localPath.Length).Replace("\\", "/");
                string remoteFile = config.remotePath + subPath;

                Progress(i, fileList.Count, totalSize);
                Log("正在上传: " + subPath + " 到 " + remoteFile);

                try {
                    SubProgress(0);
                    bool success = client.UploadFile(file, remoteFile, FtpExists.Overwrite, true, progress: this);
                    if (!success) {
                        Log("上传失败: " + subPath);
                    }
                    totalSize += CommonUtil.GetFileSize(file);
                }
                catch (System.Exception e) {
                    Debug.LogException(e);
                    Log(e);
                }
            }
            Progress(files.Length, files.Length, totalSize);

            try {
                client.Disconnect();
                client.Dispose();
            }
            catch (System.Exception e) {
                Log(e);
            }

            Log("已断开");
            client = null;
            thread = null;

            Complete();
        }

        public void Report(double value) {
            SubProgress(value / 100);
        }

    }

}
